package com.centaline.androidsalesblog.widgets;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;

import com.centaline.androidsalesblog.R;

import java.util.ArrayList;

/**
 * 自定义标签布局
 * Created by guilin on 16/2/1.
 */
public class FlowLayout extends ViewGroup {

    private static final int defualtTextColor = 0xFF333333;//默认文字颜色

    /**
     * 水平空隙.
     */
    private int horizontalSpacing;

    /**
     * 垂直空隙.
     */
    private int verticalSpacing;

    /**
     * {@link TagView}水平padding.
     */
    private int horizontalPadding;

    /**
     * {@link TagView}垂直padding.
     */
    private int verticalPadding;

    /**
     * {@link TagView}文字大小
     */
    private float textSize;

    /**
     * {@link TagView}文字颜色
     */
    private int textColor;

    /**
     * {@link TagView}Drawable资源
     */
    private int textDrawableLeft, textDrawableTop, textDrawableRight, textDrawableBottom;

    /**
     * {@link TagView}Drawable padding
     */
    private int drawablePadding;

    public FlowLayout(Context context) {
        this(context, null);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FlowLayout);
        try {
            horizontalSpacing = (int) a.getDimension(R.styleable.FlowLayout_fl_horizontalSpacing, dp2px(8.0f));
            verticalSpacing = (int) a.getDimension(R.styleable.FlowLayout_fl_verticalSpacing, dp2px(4.0f));
            horizontalPadding = (int) a.getDimension(R.styleable.FlowLayout_fl_horizontalPadding, dp2px(3.0f));
            verticalPadding = (int) a.getDimension(R.styleable.FlowLayout_fl_verticalPadding, dp2px(3.0f));
            textColor = a.getColor(R.styleable.FlowLayout_fl_textColor, defualtTextColor);
            textSize = a.getDimension(R.styleable.FlowLayout_fl_textSize, sp2px(16.0f));
            textDrawableLeft = a.getResourceId(R.styleable.FlowLayout_fl_textDrawableLeft, 0);
            textDrawableTop = a.getResourceId(R.styleable.FlowLayout_fl_textDrawableTop, 0);
            textDrawableRight = a.getResourceId(R.styleable.FlowLayout_fl_textDrawableRight, 0);
            textDrawableBottom = a.getResourceId(R.styleable.FlowLayout_fl_textDrawableBottom, 0);
            drawablePadding = (int) a.getDimension(R.styleable.FlowLayout_fl_drawablePadding, dp2px(5.0f));
        } finally {
            a.recycle();
        }

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        final int paddingLeft = getPaddingLeft();
        final int paddingRight = getPaddingRight();

        measureChildren(widthMeasureSpec, heightMeasureSpec);

        int width;
        int height = 0;

        int row = 0; // The row counter.
        int rowWidth = 0; // Calc the current row width.
        int rowMaxHeight = 0; // Calc the max tag height, in current row.

        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final int childWidth = child.getMeasuredWidth();
            final int childHeight = child.getMeasuredHeight();

            if (child.getVisibility() != GONE) {
                rowWidth += childWidth;
                if (rowWidth + paddingLeft + paddingRight > widthSize) { // Next line.
                    rowWidth = childWidth; // The next row width.
                    height += rowMaxHeight + verticalSpacing;
                    rowMaxHeight = childHeight; // The next row max height.
                    row++;
                } else { // This line.
                    rowMaxHeight = Math.max(rowMaxHeight, childHeight);
                }
                rowWidth += horizontalSpacing;
            }
        }
        // Account for the last row height.
        height += rowMaxHeight;

        // Account for the padding too.
        height += getPaddingTop() + getPaddingBottom();

        // If the tags grouped in one row, set the width to wrap the tags.
        if (row == 0) {
            width = rowWidth;
            width += getPaddingLeft() + getPaddingRight();
        } else {// If the tags grouped exceed one line, set the width to match the parent.
            width = widthSize;
        }

        setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width,
                heightMode == MeasureSpec.EXACTLY ? heightSize : height);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int parentLeft = getPaddingLeft();
        final int parentRight = r - l - getPaddingRight();
        final int parentTop = getPaddingTop();
//        final int parentBottom = b - t - getPaddingBottom();

        int childLeft = parentLeft;
        int childTop = parentTop;

        int rowMaxHeight = 0;

        final int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final int width = child.getMeasuredWidth();
            final int height = child.getMeasuredHeight();

            if (childLeft + width > parentRight) { // Next line
                childLeft = parentLeft;
                childTop += rowMaxHeight + verticalSpacing;
                rowMaxHeight = height;
            } else {
                rowMaxHeight = Math.max(rowMaxHeight, height);
            }
            child.layout(childLeft, childTop, childLeft + width, childTop + height);

            childLeft += width + horizontalSpacing;
        }
    }

    protected float dp2px(float dp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getResources().getDisplayMetrics());
    }

    protected float sp2px(float sp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
                getResources().getDisplayMetrics());
    }

    /**
     * 添加单个标签
     */
    public void addTag(String tag) {
        removeAllViews();
        if (tag == null)
            throw new NullPointerException("tag不能为空");
        appendTag(tag);
    }

    /**
     * 添加标签组
     */
    public void addTags(ArrayList<String> tags) {
        removeAllViews();
        if (tags == null)
            throw new NullPointerException("tags不能为空");
        addTags(tags.toArray(new String[tags.size()]));
    }

    /**
     * 添加标签组
     */
    public void addTags(String... tags) {
        removeAllViews();
        if (tags == null)
            throw new NullPointerException("tags不能为空");
        for (String str : tags) {
            appendTag(str);
        }
    }

    /**
     * 追加标签
     */
    protected void appendTag(String tag) {
        final TagView tagView = new TagView(getContext(), tag);
        addView(tagView);
    }

    class TagView extends AppCompatTextView {

        public TagView(Context context, String text) {
            super(context);
            setPadding(horizontalPadding, verticalPadding, horizontalPadding, verticalPadding);
            setLayoutParams(new LayoutParams(
                    LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT));
            setGravity(Gravity.CENTER);
            setText(text);
            setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
            setTextColor(textColor);
            setCompoundDrawablesWithIntrinsicBounds(textDrawableLeft, textDrawableTop, textDrawableRight, textDrawableBottom);
            setCompoundDrawablePadding(drawablePadding);
        }
    }
}
